from django.http import HttpResponse
from django.core.urlresolvers import reverse
from django.shortcuts import redirect
from django.contrib import messages
import urlparse

from annoying.decorators import render_to
from openid.consumer import consumer

from core.forms import OpenIdForm
from core.models import OpenIdCredential
from core.views import index
from core.lib import auth


@render_to('login_openid.html')
def login_openid(request):
    if request.method == 'POST':
        form = OpenIdForm(request.POST)
        if form.is_valid():
            openid_url = form.cleaned_data['url']
            return redirect(login_openid_server, openid_url)
    else:
        form = OpenIdForm()

    return {'form': form}


def login_openid_server(request, url):
    openid_consumer = consumer.Consumer(request.session, None)
    try:
        openid_request = openid_consumer.begin(url)
    except consumer.DiscoveryFailure:
        messages.info(request, 'openid_server_discovery_error')
        return redirect(login_openid)
    
    if openid_request is None:
        messages.info(request, 'openid_server_discovery_error')
        return redirect(login_openid)
    else:
        url = urlparse.urlparse(request.build_absolute_uri())
        trust_root = '{0}://{1}/'.format(url.scheme, url.netloc)
        return_url = urlparse.urljoin(trust_root, reverse(process_openid))

        if openid_request.shouldSendRedirect():
            redirect_url = openid_request.redirectURL(trust_root, return_url)
            return redirect(redirect_url)
        else:
            form_html = openid_request.htmlMarkup(
                trust_root, return_url,
                form_tag_attrs={'id': 'openid_message'})
            return HttpResponse(form_html)


def process_openid(request):
    openid_consumer = consumer.Consumer(request.session, None)
    url = request.build_absolute_uri()
    info = openid_consumer.complete(request.GET, url)

    if info.status == consumer.SUCCESS:
        id = info.getDisplayIdentifier()
        openid_credential = OpenIdCredential(open_id=id)
        user = openid_credential.authenticate()
        if user is None:
            ip = request.META['REMOTE_ADDR']
            user = auth.register(openid_credential, ip)
            messages.info(request, 'automatically_registered')
        request.session['user_id'] = user.id
        return_to = request.GET.get('return_to')
        return redirect(return_to or index)
    elif info.status == consumer.CANCEL:
        messages.info(request, 'authorization_canceled')
    else:
        messages.info(request, 'authorization_error')
    return redirect(login_openid)
